/*
 * Copyright 2022 MindMotion Microelectronics Co., Ltd.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "board_init.h"
#include "SLCD/slcd.h"

/*
 * Macros.
 */
#define APP_SLCD_SEG_BITS_BUFF_LEN 2u

/*
 * Variables.
 */
volatile uint32_t app_slcd_seg_bits[APP_SLCD_SEG_BITS_BUFF_LEN];
const uint32_t app_slcd_com_pin_buff[BOARD_SLCD_COM_NUM] = {BOARD_SLCD_COM_PIN_BUFF};
const uint32_t app_slcd_seg_pin_buff[BOARD_SLCD_SEG_NUM] = {BOARD_SLCD_SEG_PIN_BUFF};

volatile uint32_t counter = 0;

/*
 * Declerations.
 */
void app_delay(uint32_t delay);
void app_slcd_init(void);
void app_slcd_display(void);

/*
 * Functions.
 */
int main(void)
{
    // 开发板初始化
    BOARD_Init();

    // SLCD初始化
    app_slcd_init();
    // SLCD清屏
    LCD_Clear();

    // 大数字区域显示
    for(uint8_t i=0;i<6;i++) {
        LCD_DisplayNumber1(i, '0'+i, 1);
        app_delay(100u);
    }
    // 小数字区域显示
    for(uint8_t i=0;i<4;i++) {
        LCD_DisplayNumber2(i, '0'+i, 1);
        app_delay(100u);
    }
    // 符号显示
    for(uint8_t i=0;i<10;i++) {
        LCD_DisplayUnit(i, 1);
        app_delay(100u);
    }

    LCD_Clear();

    // 浮点数显示测试
    double nums[] = {
        7654321,
        765432.1,
        76543.21,
        7654.321,
        765.4321,
        76.54321,
        7.654321,
        0.7654321,
        0.07654321,
        0.007654321,
        0.0007654321,
        0.00007654321,
        0.000007654321,
        0.0000007654321,
    };

    LCD_Clear();

    for(uint8_t i=0;i<=8;i++) {
        for(uint8_t j=0;j<sizeof(nums)/sizeof(nums[0]);j++) {
            LCD_DisplayFLoat1(nums[j], i);
            LCD_DisplayFLoat2(nums[j], i);
            app_delay(50u);
        }
    }

    while (1)
    {
        // SLCD段码位显示测试
        // app_slcd_display();

        // SLCD显示整体测试
        // LCD_DisplayDataUpdate();

        // SLCD大数字显示
        LCD_DisplayNumbers1(counter%1000000);
        // SLCD小数字显示
        LCD_DisplayNumbers2(counter%10000);
        // 符号显示
        LCD_DisplayUnit(counter%10, counter/10%2);
        // 延时
        app_delay(100u);
        counter++;
    }
}

// SLCD初始化
void app_slcd_init(void)
{
    /* Setup the SLCD engine. */
    SLCD_Init_Type slcd_init;
    slcd_init.ClockDiv0 = BOARD_SLCD_DIV0;
    slcd_init.ClockDiv1 = BOARD_SLCD_DIV1;
    slcd_init.ChargePumpClockDiv = BOARD_SLCD_CHARGEPUMPDIV;
    slcd_init.DutyCycle = BOARD_SLCD_DUTYCYCLE;
    slcd_init.BiasMode = BOARD_SLCD_BIASMODE;
    slcd_init.PowerSource = SLCD_PowerSource_Internal;
    slcd_init.ChargePumpMode = SLCD_ChargePumpMode_Boost;
    slcd_init.Brightness = BOARD_SLCD_BRIGHTNESS;
    slcd_init.EnableLowPowerMode = false;
    SLCD_Init(BOARD_SLCD_PORT, &slcd_init);

    /* Set common pin. */
    for (uint32_t com_x = 0; com_x < BOARD_SLCD_COM_NUM; com_x++)
    {
        SLCD_SetCOMxPinMux(BOARD_SLCD_PORT, com_x, app_slcd_com_pin_buff[com_x]);
    }

    /* Set segment pin. */
    for (uint32_t seg_y = 0; seg_y < BOARD_SLCD_SEG_NUM; seg_y++)
    {
        SLCD_SetSegBitPinMux(BOARD_SLCD_PORT, app_slcd_seg_pin_buff[seg_y]);
    }

    /* Enable SLCD. */
    SLCD_Enable(BOARD_SLCD_PORT, true);
}

void app_slcd_display(void)
{
    /* Clear all segment bits. */
    SLCD_ClearAllSegBits(BOARD_SLCD_PORT);

    for (uint32_t com_x = 0u; com_x < BOARD_SLCD_COM_NUM; com_x++)
    {
        app_slcd_seg_bits[0u] = 0u;
        app_slcd_seg_bits[1u] = 0u;

        for (uint32_t seg_y = 0u; seg_y < BOARD_SLCD_SEG_NUM; seg_y++)
        {
            if (app_slcd_seg_pin_buff[seg_y] < 32u)
            {
                app_slcd_seg_bits[0u] |= (1u << app_slcd_seg_pin_buff[seg_y] ); /* Segment 0 ~ 31 bit mask. */
            }
            else
            {
                app_slcd_seg_bits[1u] |= (1u << (app_slcd_seg_pin_buff[seg_y] - 32u) ); /* Segment 32 ~ 63 bit mask. */
            }

            /* Set COMx segment bits to display. */
            SLCD_SetCOMxSegBits(BOARD_SLCD_PORT, com_x, (uint32_t * )app_slcd_seg_bits);

            app_delay(5u);
        }
    }
}

void app_delay(uint32_t delay)
{
    for (uint32_t i = 0u; i < delay; i++)
    {
        for (uint32_t j = 0u; j < BOARD_DELAY_COUNT; j++)
        {
            __NOP();
        }
    }
}

/* EOF. */
